/**
 * 创建一个可拖拽的矩形
 */
function CreateDragRect(elm, options = {}) {
  // console.log(options);
  if (!elm) throw new Error("el 必须是一个document对象");
  this.rect = elm;
  this.isLeftMove = true;
  this.isTopMove = true;
  this.rectDefaultPosition = options.position || "absolute";
  this.minX = options.minX || null;
  this.minY = options.minY || null;
  this.maxX = options.maxX || null;
  this.maxY = options.maxY || null;
  this.rectDefaultLeft = options.rectDefaultLeft || 0;
  this.rectDefaultTop = options.rectDefaultTop || 0;
  this.rectWidth = options.rectWidth || 100;
  this.rectHeight = options.rectHeight || 100;
  this.rectMinWidth = options.rectMinWidth || 5; //最小宽度(超过之后不允许再缩放)
  this.rectMinHeight = options.rectMinHeight || 5; //最小高度(超过之后不允许再缩放)
  this.rectMaxWidth = options.rectMaxWidth; //最大宽度(超过之后不允许再缩放)
  this.rectMaxHeight = options.rectMaxHeight; //最大高度(超过之后不允许再缩放)
  this.rectBackgroundColor = options.rectBackgroundColor || "transparent";
  this.dragIconSize = options.dragIconSize || "4";
  this.dragIconColor = options.dragIconColor || "#f00";
  //主矩形是否可以移动
  this.isMove = false;
  this.initStyle();
  this.bindDragEvent(this.rect);
}

/**
 * 主矩形绑定move事件
 */
CreateDragRect.prototype.bindDragEvent = function (dom, position) {
  const _this = this;
  dom.onmousedown = function (event) {
    event.stopPropagation();
    //按下矩形的时候可以移动，否则不可移动
    _this.isMove = !position; //false left-bottom
    // 获取鼠标在wrapper中的位置
    let boxX = event.clientX - dom.offsetLeft;
    let boxY = event.clientY - dom.offsetTop;
    //鼠标移动事件(如果计算太高,有拖影)
    document.onmousemove = _this.throttle(function (moveEv) {
      let ev = moveEv || window.event;
      ev.stopPropagation();
      let moveX = ev.clientX - boxX;
      let moveY = ev.clientY - boxY;
      switch (position) {
        case "top-left": //左上: 需计算top left width
          _this.nwRectSize(moveX, moveY);
          break;
        case "top-right": //右上 计算top 和 height
          _this.neRectSize(moveX, moveY);
          break;
        case "right-bottom": //只需计算当前鼠标位置
          _this.seRectSize(moveX, moveY);
          break;
        case "left-bottom": //计算left偏移量，计算w
          _this.swRectSize(moveX, moveY);
          break;
        default:
          //拖拽矩形
          if (!_this.isMove) return null;
          _this.moveRect(ev.clientX - boxX, ev.clientY - boxY);
      }
    }, 15);

    //鼠标松开，移除事件
    document.onmouseup = function (event) {
      document.onmousemove = null;
      document.onmouseup = null;
      // 存储当前的rect的宽高
      _this.rectWidth = _this.rect.offsetWidth;
      _this.rectHeight = _this.rect.offsetHeight;
      // 获得当前矩形的offsetLeft 和 offsetTop
      _this.rectOffsetLeft = _this.rect.offsetLeft;
      _this.rectOffsetTop = _this.rect.offsetTop;
    };
  };
};

/**
 * 初始化样式
 */
CreateDragRect.prototype.initStyle = function () {
  this.rect.style.position = this.rectDefaultPosition;
  this.rect.style.width = this.rectWidth + "px";
  this.rect.style.height = this.rectHeight + "px";
  this.rect.style.left = this.rectDefaultLeft + "px";
  this.rect.style.top = this.rectDefaultTop + "px";
  this.rect.style.background = this.rectBackgroundColor;
  this.rect.style.border = "1px solid #333";
  //依次为上 右 下 左
  let dragIcons = [
    {
      cursor: "nw-resize",
      x: "top",
      y: "left",
    },
    {
      cursor: "ne-resize",
      x: "top",
      y: "right",
    },
    {
      cursor: "se-resize",
      x: "right",
      y: "bottom",
    },
    {
      cursor: "sw-resize",
      x: "left",
      y: "bottom",
    },
  ];
  for (let i = 0, l = dragIcons.length; i < l; i++) {
    let icon = document.createElement("i");
    icon.id = Math.random().toString(36).substring(7);
    icon.style.display = "inline-block";
    icon.style.width = this.dragIconSize + "px";
    icon.style.height = this.dragIconSize + "px";
    icon.style.position = "absolute";
    icon.style.zIndex = 10;
    icon.style.cursor = dragIcons[i].cursor;
    icon.style.backgroundColor = this.dragIconColor;
    icon.style[dragIcons[i].x] = -parseInt(icon.style.width) / 2 + "px";
    icon.style[dragIcons[i].y] = -parseInt(icon.style.height) / 2 + "px";
    //绑定四个角的拖拽事件
    // left-bottom
    this.bindDragEvent(icon, `${dragIcons[i].x}-${dragIcons[i].y}`);
    //插入到矩形
    this.rect.appendChild(icon);
  }
};

/**
 * 移动主矩形
 */
CreateDragRect.prototype.moveRect = function (x, y) {
  if (this.isTopMove && this.isLeftMove) {
    // console.log("moveRect", x, this.minX);
    // 处理边界
    if (this.minX) {
      x = x < this.minX ? this.minX : x;
    }
    if (this.minY) {
      y = y < this.minY ? this.minY : y;
    }
    // 最大值需要减去自身宽度
    if (this.maxX) {
      x = x > this.maxX - this.rectWidth ? this.maxX - this.rectWidth : x;
    }
    if (this.maxY) {
      y = y > this.maxY - this.rectHeight ? this.maxY - this.rectHeight : y;
    }
    this.rect.style.left = x + "px";
    this.rect.style.top = y + "px";
  }
};

/**
 * 移动主矩形缩放 - 左上
 */
CreateDragRect.prototype.nwRectSize = function (x, y) {
  //计算是否是最小宽度
  const { width, height, isLeftMove, isTopMove } = this.getMinSize(
    this.rectWidth - x,
    this.rectHeight - y
  );
  if (isTopMove) {
    this.rect.style.top = this.rectOffsetTop + y + "px";
    this.rect.style.height = height + "px";
  }
  if (isLeftMove) {
    this.rect.style.left = this.rectOffsetLeft + x + "px";
    this.rect.style.width = width + "px";
  }
};

/**
 * 移动主矩形缩放 - 左下
 */
CreateDragRect.prototype.swRectSize = function (x, y) {
  //计算是否是最小宽度
  const { width, height, isLeftMove, isTopMove } = this.getMinSize(
    this.rectWidth - x,
    y
  );
  if (isLeftMove) {
    this.rect.style.left = this.rectOffsetLeft + x + "px";
    this.rect.style.width = width + "px";
  }
  if (isTopMove) {
    this.rect.style.height = height + "px";
  }
};

/**
 * 移动主矩形缩放 - 右上
 */
CreateDragRect.prototype.neRectSize = function (x, y) {
  //计算是否是最小宽度
  const { width, height, isTopMove, isLeftMove } = this.getMinSize(
    x,
    this.rectHeight - y
  );
  if (isTopMove) {
    this.rect.style.height = height + "px";
    this.rect.style.top = this.rectOffsetTop + y + "px";
  }
  if (isLeftMove) {
    this.rect.style.width = width + "px";
  }
};

/**
 * 移动主矩形缩放 - 右下
 */
CreateDragRect.prototype.seRectSize = function (x, y) {
  //计算是否是最小宽度 4
  const { width, height } = this.getMinSize(x, y);
  this.rect.style.width = width + "px";
  this.rect.style.height = height + "px";
};

/**
 * 节流函数
 * @param {*} fn
 * @param {*} delay
 */
CreateDragRect.prototype.throttle = function (fn, delay) {
  let last = 0;
  return function () {
    let curr = Date.now();
    if (curr - last > delay) {
      fn.apply(this, arguments);
      last = curr;
    }
  };
};

/**
 * 获取宽高 边界判断
 * @param {*} w
 * @param {*} h
 * @return { Object }
 */
CreateDragRect.prototype.getMinSize = function (w, h) {
  let resWidth = this.rectMinWidth; // 5
  let resHeight = this.rectMinHeight;
  //x拖拽  宽度是否大于最小宽  4>=5
  this.isLeftMove = w >= this.rectMinWidth;
  //y拖拽
  this.isTopMove = h >= this.rectMinHeight;
  if (this.isLeftMove) resWidth = w;
  if (this.isTopMove) resHeight = h;

  // 最大值限制
  if (this.rectMaxWidth) {
    resWidth = w > this.rectMaxWidth ? this.rectMaxWidth : w;
  }
  if (this.rectMaxHeight) {
    resHeight = h > this.rectMaxHeight ? this.rectMaxHeight : h;
  }

  console.log(resWidth);
  return {
    width: resWidth,
    height: resHeight,
    isLeftMove: this.isLeftMove,
    isTopMove: this.isTopMove,
  };
};

export default CreateDragRect;
